<script setup lang="ts">
import { ref, onMounted, nextTick } from "vue"
import { ElMessage, ElMessageBox } from 'element-plus'
import { updateCertificateTempApi, previewCertificateApi } from "#/api/certificate/template"
import { trimStringParams } from '#/utils/trimStringParams'
import { cloneDeep } from '@vben/utils';
import { $t } from '#/locales'
import { templateAttribute, examplePreviewInfo } from "./const"
import { DrawCanvas } from "./index"
import { Trash2, Play, IconifyIcon } from '@vben/icons'
import { previewPdf, isPdfResponse } from "#/utils/pdfUtils"
const drawCanvasRef = ref()

import type {
  TempTextConfig,
  CertificateTemplateFormData,
  TemplateAttribute
} from "./types"
import { isValidJSON } from "#/utils/isValidJSON";

defineOptions({ name: 'Dialog' })

const emit = defineEmits(['queryTable'])
const fontSizeList = ref<{ label: string; value: number }[]>([])
const submitLoading = ref(false)
const previewLoading = ref(false)
const dialogVisible = ref(false)
const editData = ref()
const defaultFrom: CertificateTemplateFormData = {
  id: '',
  certificationId: '',
  templateFile: '',
  tempTextConfigs: []
}
const formRef = ref()
const formInline = ref<CertificateTemplateFormData>(cloneDeep(defaultFrom))
const canvasInfo = ref({
  devicePixelRatio: 1,
  scaleX: 1,
  scaleY: 1,
  canvasImgWidth: 0,
  canvasImgHeight: 0,
  imgWidth: 0,
  imgHeight: 0
})

const handleClose = () => {
  if (editData.value.draft === JSON.stringify(restoreCanvasInfo())) {
    initForm()
    return
  }
  const message = $t('certificateTemplate.saveDraftTxt');
  ElMessageBox.confirm(message, $t('common.tipTxt'), {
    confirmButtonText: $t('common.saveTxt'),
    cancelButtonText: $t('common.noSaveTxt'),
    closeOnClickModal: false,
    closeOnPressEscape: false,
    type: 'warning',
  }).then(() => {
    submit('draft')
  }).catch(() => {
    initForm()
  })
}

const initForm = () => {
  formInline.value = cloneDeep(defaultFrom)
  dialogVisible.value = false
  formRef.value?.resetFields()
}

const inint = (data: any = null) => {
  if (data) {
    const { tempTextConfigs, draft } = data
    // 如果draft存在，则使用draft，否则使用tempTextConfigs
    const tcfs = !!draft ? draft : tempTextConfigs
    if (!!tcfs && isValidJSON(tcfs)) {
      console.log(JSON.parse(tcfs))
      formInline.value.tempTextConfigs = JSON.parse(tcfs).map((item: any) => ({
        ...item,
        name: templateAttribute.find((attr: any) => attr.fieldName === item.fieldName)?.name,
        x: Number((item.x).toFixed(2)),
        y: Number((item.y).toFixed(2)),
        fontBold: item.fontBold === 'true',
        alignCenter: item.alignCenter,
        isActive: false,
        exampleValue: templateAttribute.find((attr: any) => attr.fieldName === item.fieldName)?.exampleValue || ''
      }))
    } else {
      formInline.value.tempTextConfigs = []
    }
    editData.value = data
  }
  dialogVisible.value = true
}

const handleAddAttribute = (attr: TemplateAttribute) => {
  if (formInline.value.tempTextConfigs.find((item: any) => item.fieldName === attr.fieldName)) {
    ElMessage.warning($t('certificateTemplate.attributeExistTxt'))
    return
  }

  // 找到当前属性在 templateAttribute 中的索引
  const attrIndex = templateAttribute.findIndex((item: any) => item.fieldName === attr.fieldName)

  // 找到应该插入的位置（按照 templateAttribute 的顺序）
  let insertIndex = 0
  for (let i = 0; i < formInline.value.tempTextConfigs.length; i++) {
    const currentItem = formInline.value.tempTextConfigs[i]
    if (currentItem) {
      const currentIndex = templateAttribute.findIndex((item: any) => item.fieldName === currentItem.fieldName)
      if (currentIndex > attrIndex) {
        insertIndex = i
        break
      }
    }
    insertIndex = i + 1
  }

  // 在正确的位置插入新属性
  formInline.value.tempTextConfigs.splice(insertIndex, 0, {
    name: attr.name,
    fieldName: attr.fieldName,
    x: attr.x,
    y: attr.y,
    alignCenter: false,
    fontColor: '#000000',
    fontBold: false,
    fontItalic: false,
    fontType: 'SYHEITICN_LIGHT',
    fontSize: attr.fontSize,
    isActive: true,
    exampleValue: attr.exampleValue || ''
  })
}

const handleDeleteAttribute = (configs: TempTextConfig) => {
  formInline.value.tempTextConfigs = formInline.value.tempTextConfigs.filter((item: any) => item.fieldName !== configs.fieldName)
}

const handleTextConfigsUpdate = (configs: TempTextConfig[]) => {
  formInline.value.tempTextConfigs = configs
}

const handlePlay = (item: TempTextConfig) => {
  item.isActive = !item.isActive
}

const handleAlignCenter = (command: string, item: TempTextConfig) => {
  item.alignCenter = command === 'center'
}
// 还原坐标
const restoreCanvasInfo = () => {
  const config = cloneDeep(formInline.value.tempTextConfigs)
  const sX = canvasInfo.value.canvasImgWidth / canvasInfo.value.imgWidth
  const sY = canvasInfo.value.canvasImgHeight / canvasInfo.value.imgHeight
  config.forEach((item: any) => {
    // 还原X坐标：Canvas坐标 / 缩放比例
    item.x = Number((item.x / sX).toFixed(0))
    // 还原Y坐标：Canvas高度 - Canvas Y坐标 / 缩放比例
    item.y = Number(((canvasInfo.value.canvasImgHeight - item.y - item.fontSize + canvasInfo.value.devicePixelRatio) / sY).toFixed(0))
    // 还原字体大小：Canvas字体大小 / 最小缩放比例
    item.fontSize = Number((item.fontSize / Math.min(sX, sY)).toFixed(0))
  })
  return config
}

const handlePreview = () => {
  previewLoading.value = true
  const params = {
    examplePreviewInfo: examplePreviewInfo.previewInfo,
    tempTextConfigs: restoreCanvasInfo(),
    templateFile: editData.value.templateFile
  }
  previewCertificateApi(params).then((res: any) => {
    console.log(res)
    if (isPdfResponse(res)) {
      previewPdf(res)
    } else {
      ElMessage.error($t('common.previewFailedTxt'))
    }
  }).catch((err: any) => {
    console.log(err)
  }).finally(() => {
    previewLoading.value = false
  })
}

const submit = (type?: string) => {
  // if (!formRef) return
  // formRef.value?.validate((valid: any) => {
  //   if (valid) {
  const oldData = isValidJSON(editData.value.tempTextConfigs) ? JSON.parse(editData.value.tempTextConfigs) : null
  const params = {
    id: editData.value.id,
    certificationId: editData.value.certificationId,
    templateFile: editData.value.templateFile,
    tempTextConfigs: type === 'draft' ? oldData : restoreCanvasInfo(),
    draftContent: type === 'draft' ? JSON.stringify(restoreCanvasInfo()) : null
  }
  submitLoading.value = true
  const API = updateCertificateTempApi(trimStringParams(params))
  API.then(() => {
    initForm()
    type === 'draft' ? ElMessage.success($t('common.saveTxt', [$t('common.successTxt')])) : ElMessage.success($t('common.handleTxt', [$t('common.successTxt')]))
    dialogVisible.value = false
    emit('queryTable')
  }).finally(() => {
    submitLoading.value = false
  })
  //   }
  // })
}

const handleCanvasInfo = (info: any) => {
  console.log(info)
  canvasInfo.value = info
}

const handleFontBold = (item: TempTextConfig) => {
  item.fontBold = !item.fontBold
  item.fontType = item.fontBold ? 'SYHEITICN_REGULAR' : 'SYHEITICN_LIGHT'
}

onMounted(() => {
  fontSizeList.value = Array.from({ length: 51 }, (_, index) => index + 10).map((item: number) => {
    return {
      label: `${item}px`,
      value: item
    }
  })
})

defineExpose({ inint })

</script>
<template>
  <el-drawer id="mock-template-drawer" :destroy-on-close="true" :close-on-click-modal="false"
    :close-on-press-escape="false" :append-to-body="true" body-class="drawer-canvas-body" :with-header="false"
    class="detail-war" size="100%" v-model="dialogVisible" direction="rtl">
    <template #header class="h-0">
      <h4 class="detail-title text-black font-bold">{{ $t('certificateTemplate.designTemplateTxt') }}</h4>
    </template>
    <template #default>
      <div class="flex h-full">
        <div class="flex-none w-[360px] h-full bg-[#fff] flex flex-col pl-[24px] pt-[16px] pr-[24px] pb-[16px]">
          <div class="border-b border-[#ebeef5] pb-[24px] mb-[24px]">
            <div class="text-[#191919] font-[500] mb-[10px]">{{ $t('certificateTemplate.addContentTxt') }}</div>
            <div class="grid grid-cols-3 gap-[10px]">
              <div v-for="attr in templateAttribute" @click="handleAddAttribute(attr)" :key="attr.fieldName"
                class="text-center cursor-pointer border border-[#DCDFE6] rounded-[4px] p-[10px] select-none"
                :style="{ borderColor: formInline.tempTextConfigs.find((item: any) => item.fieldName === attr.fieldName) ? '#007AFF' : '#DCDFE6' }">
                <div class="text-[#191919]">{{ attr.name }}</div>
              </div>
            </div>
          </div>
          <el-form class="w-full flex-1 overflow-y-auto" label-position="top">
            <el-form-item class="w-full" v-for="item in formInline.tempTextConfigs" :label="item.name"
              :key="item.fieldName">
              <template #label>
                <div
                  class="w-full flex items-center justify-between bg-[#F2F7FD] rounded-[4px] p-[5px] text-[#191919] font-[500]">
                  <div @click="handlePlay(item)" class="cursor-pointer select-none">
                    <Play fill="#595959" class="text-[#595959] play-icon scale-[0.6] inline-block align-top"
                      :class="{ 'play-icon-active': item.isActive }"></Play>
                    <span>{{ item.name }}</span>
                  </div>
                  <el-button link :icon="Trash2" @click="handleDeleteAttribute(item)" />
                </div>
              </template>
              <template #default>
                <div :class="{ 'hidden': !item.isActive }" class="pt-[10px] transition-all duration-200">
                  <div class="flex items-center gap-[5px] mb-[10px]">
                    <span>{{ $t('certificateTemplate.fontSize2Txt') }}</span>
                    <el-select v-model="item.fontSize" class="w-[143px]"
                      :placeholder="$t('certificateTemplate.fontSizeTxt')">
                      <el-option v-for="size in fontSizeList" :key="size.value" :label="size.label"
                        :value="size.value" />
                    </el-select>
                    <div
                      class="h-[16px] leading-[16px] flex items-center border-l border-[#DCDFE6] ml-[16px] pl-[16px]">
                      <el-tooltip effect="dark" :content="$t('certificateTemplate.colorSettingTxt')" :show-after="1000"
                        placement="top">
                        <span class="inline-block h-[14px]">
                          <el-color-picker :style="`background-color: ${item.fontColor || '#000000'};`"
                            v-model="item.fontColor" />
                        </span>
                      </el-tooltip>
                      <el-tooltip effect="dark"
                        :content="`${item.fontBold ? $t('certificateTemplate.fontBoldCancelTxt') : $t('certificateTemplate.fontBoldTxt')}`"
                        :show-after="1000" placement="top">
                        <el-button link @click="handleFontBold(item)"
                          :style="{ fontWeight: item.fontBold ? '700' : 'normal' }"
                          class="inline-block w-[15px] text-[#007AFF] text-[16px] ml-[12px] mr-[12px]">B</el-button>
                      </el-tooltip>

                      <el-dropdown trigger="click" @command="handleAlignCenter($event, item)">
                        <div class="el-dropdown-link">
                          <el-tooltip effect="dark" :content="$t('certificateTemplate.alignCenterSettingTxt')"
                            :show-after="1000" placement="top">
                            <div class=" flex items-center">
                              <IconifyIcon
                                :icon="`lucide:${item.alignCenter ? 'align-center-vertical' : 'align-start-vertical'}`" />
                              <el-icon>
                                <Play fill="#595959"
                                  class="text-[#595959] play-icon scale-[0.6] inline-block align-top rotate-90"></Play>
                              </el-icon>
                            </div>
                          </el-tooltip>
                        </div>
                        <template #dropdown>
                          <el-dropdown-menu>
                            <el-dropdown-item :class="{ 'text-[#007AFF]': !item.alignCenter }" command="left">
                              {{ $t('certificateTemplate.alignLeftTxt') }}
                            </el-dropdown-item>
                            <el-dropdown-item :class="{ 'text-[#007AFF]': item.alignCenter }" command="center">
                              {{ $t('certificateTemplate.alignCenterTxt') }}
                            </el-dropdown-item>
                          </el-dropdown-menu>
                        </template>
                      </el-dropdown>
                    </div>
                  </div>
                  <div class="flex gap-[5px] mb-[10px]">
                    <span>{{ $t('certificateTemplate.positionTxt') }}</span>
                    <span>X</span><el-input-number :controls="false" class="w-[100px] mr-[25px]" type="number"
                      v-model="item.x" :placeholder="$t('certificateTemplate.xTxt')" />
                    <span>Y</span><el-input-number :controls="false" class="w-[100px]" type="number" v-model="item.y"
                      :placeholder="$t('certificateTemplate.yTxt')" />
                  </div>
                </div>
              </template>
            </el-form-item>
          </el-form>
        </div>
        <div class="flex-auto canvas p-[20px]">
          <DrawCanvas ref="drawCanvasRef" :templateFile="editData?.templateFile"
            :tempTextConfigs="formInline.tempTextConfigs" @update:tempTextConfigs="handleTextConfigsUpdate"
            @update:canvasInfo="handleCanvasInfo" />
        </div>
      </div>
    </template>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">
          {{ $t('common.cancelTxt') }}
        </el-button>
        <el-button :loading="previewLoading" @click="handlePreview">
          {{ $t('common.previewTxt') }}
        </el-button>
        <el-button type="primary" :loading="submitLoading" @click="submit">
          {{ $t('common.submitTxt') }}
        </el-button>
      </div>
    </template>
  </el-drawer>
</template>
<style lang="scss" scoped>
:deep(.el-form--inline .el-form-item) {
  margin-right: 0px;
}

.hide-upload-btn :deep(.el-upload--picture-card) {
  display: none !important;
}

:deep(.el-form-item__label) {
  display: block;
  width: 100%;
  padding: 0px;
}

.play-icon {
  cursor: pointer;
  transition: transform 0.2s;
}

.play-icon-active {
  transform: rotate(90deg) scale(0.6);
  transition: transform 0.2s;
}

:deep(.el-form-item--label-top .el-form-item__label) {
  margin-bottom: 0px;
}

:deep(.el-color-picker),
:deep(.el-color-picker__trigger) {
  width: 14px;
  height: 14px;
  line-height: 0px;
  padding: 0px;
  border: none;
  border-radius: 7px;
  overflow: hidden;

  span,
  i,
  svg {
    display: none;
  }
}
</style>
<style lang="scss">
#mock-template-drawer .drawer-canvas-body {
  padding: 0px !important;
  background-color: #EDEEF5 !important;
}
</style>
